/**
 * STM32F103 智能农业大棚监控系统
 * 功能：传感器数据采集、自动控制、WiFi通信
 * 作者：Inscode AI
 * 日期：2025-12-03
 */

#include "stm32f10x.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

// 传感器驱动头文件
#include "sht30.h"
#include "mhz19b.h"
#include "bh1750.h"
#include "ssd1306.h"
#include "esp8266.h"

// 系统配置
#define NODE_ID 1                    // 大棚节点ID (1-8)
#define DATA_UPLOAD_INTERVAL 30000   // 数据上传间隔 30秒
#define CONTROL_INTERVAL 10000       // 控制周期 10秒

// 作物模板配置
typedef struct {
    char name[16];           // 作物名称
    float soil_temp_min;     // 土壤温度最小值
    float soil_temp_max;     // 土壤温度最大值
    float soil_humidity_min; // 土壤湿度最小值
    float soil_humidity_max; // 土壤湿度最大值
    float co2_min;          // CO2最小值
    float co2_max;          // CO2最大值
    float light_min;        // 光照最小值 (lux)
    float light_max;        // 光照最大值 (lux)
} CropTemplate;

// 传感器数据结构
typedef struct {
    float soil_temperature;   // 土壤温度 (°C)
    float soil_humidity;      // 土壤湿度 (%)
    float air_co2;           // 空气CO2浓度 (ppm)
    float light_intensity;   // 光照强度 (lux)
    uint32_t timestamp;      // 时间戳
} SensorData;

// 系统状态
typedef struct {
    uint8_t pump_status;     // 水泵状态 (0:关闭, 1:开启)
    uint8_t heater_status;   // 加热灯状态 (0:关闭, 1:开启)
    uint8_t wifi_connected;  // WiFi连接状态
    uint8_t auto_mode;       // 自动模式 (0:手动, 1:自动)
    uint8_t current_crop;    // 当前作物模板索引
} SystemStatus;

// 全局变量
SensorData g_sensor_data;
SystemStatus g_system_status;
CropTemplate g_crop_templates[3];
uint32_t g_last_upload_time = 0;
uint32_t g_last_control_time = 0;

// 函数声明
void System_Init(void);
void GPIO_Init_Config(void);
void Timer_Init_Config(void);
void USART_Init_Config(void);
void I2C_Init_Config(void);
void ADC_Init_Config(void);

void Sensor_Read_All(void);
void Control_Execute(void);
void Data_Upload(void);
void OLED_Display_Data(void);
void Alarm_Check(void);

void Delay_ms(uint32_t ms);
void Delay_us(uint32_t us);

// 作物模板初始化
void Crop_Templates_Init(void) {
    // 番茄模板
    strcpy(g_crop_templates[0].name, "番茄");
    g_crop_templates[0].soil_temp_min = 18.0;
    g_crop_templates[0].soil_temp_max = 25.0;
    g_crop_templates[0].soil_humidity_min = 40.0;
    g_crop_templates[0].soil_humidity_max = 60.0;
    g_crop_templates[0].co2_min = 800.0;
    g_crop_templates[0].co2_max = 1200.0;
    g_crop_templates[0].light_min = 20000.0;
    g_crop_templates[0].light_max = 50000.0;
    
    // 草莓模板
    strcpy(g_crop_templates[1].name, "草莓");
    g_crop_templates[1].soil_temp_min = 15.0;
    g_crop_templates[1].soil_temp_max = 20.0;
    g_crop_templates[1].soil_humidity_min = 50.0;
    g_crop_templates[1].soil_humidity_max = 70.0;
    g_crop_templates[1].co2_min = 600.0;
    g_crop_templates[1].co2_max = 1000.0;
    g_crop_templates[1].light_min = 15000.0;
    g_crop_templates[1].light_max = 40000.0;
    
    // 通用模板
    strcpy(g_crop_templates[2].name, "通用");
    g_crop_templates[2].soil_temp_min = 16.0;
    g_crop_templates[2].soil_temp_max = 24.0;
    g_crop_templates[2].soil_humidity_min = 45.0;
    g_crop_templates[2].soil_humidity_max = 65.0;
    g_crop_templates[2].co2_min = 700.0;
    g_crop_templates[2].co2_max = 1100.0;
    g_crop_templates[2].light_min = 18000.0;
    g_crop_templates[2].light_max = 45000.0;
}

// 主函数
int main(void) {
    System_Init();
    
    printf("STM32 智能农业大棚监控系统启动...\r\n");
    printf("节点ID: %d\r\n", NODE_ID);
    
    // 初始化作物模板
    Crop_Templates_Init();
    g_system_status.current_crop = 0; // 默认番茄
    g_system_status.auto_mode = 1;    // 默认自动模式
    
    // 初始化传感器
    SHT30_Init();
    MHZ19B_Init();
    BH1750_Init();
    SSD1306_Init();
    ESP8266_Init();
    
    printf("系统初始化完成\r\n");
    
    while (1) {
        uint32_t current_time = millis();
        
        // 读取传感器数据
        Sensor_Read_All();
        
        // OLED显示
        OLED_Display_Data();
        
        // 自动控制
        if (g_system_status.auto_mode && 
            (current_time - g_last_control_time >= CONTROL_INTERVAL)) {
            Control_Execute();
            g_last_control_time = current_time;
        }
        
        // 数据上传
        if (current_time - g_last_upload_time >= DATA_UPLOAD_INTERVAL) {
            Data_Upload();
            g_last_upload_time = current_time;
        }
        
        // 报警检查
        Alarm_Check();
        
        Delay_ms(100);
    }
}

// 系统初始化
void System_Init(void) {
    // 初始化系统时钟
    SystemCoreClockUpdate();
    
    // 初始化各个模块
    GPIO_Init_Config();
    Timer_Init_Config();
    USART_Init_Config();
    I2C_Init_Config();
    ADC_Init_Config();
    
    // 初始化全局变量
    memset(&g_sensor_data, 0, sizeof(SensorData));
    memset(&g_system_status, 0, sizeof(SystemStatus));
}

// GPIO初始化配置
void GPIO_Init_Config(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能GPIO时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | 
                          RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
    
    // 水泵控制引脚 (PC0)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOC, GPIO_Pin_0); // 默认关闭
    
    // 加热灯控制引脚 (PC1)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOC, GPIO_Pin_1); // 默认关闭
    
    // 蜂鸣器引脚 (PC2)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOC, GPIO_Pin_2); // 默认关闭
    
    // LED状态指示灯 (PC3)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOC, GPIO_Pin_3); // 默认关闭
}

// 定时器初始化配置
void Timer_Init_Config(void) {
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    
    // 使能定时器时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    
    // 配置定时器2为1ms中断
    TIM_TimeBaseStructure.TIM_Period = 999;
    TIM_TimeBaseStructure.TIM_Prescaler = 71;
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
    
    // 使能定时器中断
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    
    // 配置NVIC
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    // 启动定时器
    TIM_Cmd(TIM2, ENABLE);
}

// USART初始化配置
void USART_Init_Config(void) {
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能USART1时钟 (用于调试)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置USART1 Tx (PA9)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置USART1 Rx (PA10)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // USART1配置 (调试串口)
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);
    
    // 使能USART2时钟 (用于ESP8266)
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置USART2 Tx (PA2)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置USART2 Rx (PA3)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // USART2配置 (ESP8266)
    USART_InitStructure.USART_BaudRate = 115200;
    USART_Init(USART2, &USART_InitStructure);
    USART_Cmd(USART2, ENABLE);
}

// I2C初始化配置
void I2C_Init_Config(void) {
    I2C_InitTypeDef I2C_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能I2C1时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
    // 配置I2C1 SCL (PB6)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    // 配置I2C1 SDA (PB7)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    
    // I2C1配置
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x30;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = 100000; // 100kHz
    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_Cmd(I2C1, ENABLE);
}

// ADC初始化配置
void ADC_Init_Config(void) {
    ADC_InitTypeDef ADC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    
    // 使能ADC1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置ADC引脚 (PA0, PA1, PA4, PA5, PA6, PA7)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | 
                                  GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // ADC配置
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 6;
    ADC_Init(ADC1, &ADC_InitStructure);
    
    // 配置ADC通道
    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 4, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 5, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 6, ADC_SampleTime_55Cycles5);
    
    // 启动ADC
    ADC_Cmd(ADC1, ENABLE);
    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1));
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

// 读取所有传感器数据
void Sensor_Read_All(void) {
    // 读取土壤温湿度 (SHT30)
    if (SHT30_Read(&g_sensor_data.soil_temperature, &g_sensor_data.soil_humidity) == 0) {
        printf("土壤温湿度读取失败\r\n");
    }
    
    // 读取CO2浓度 (MH-Z19B)
    g_sensor_data.air_co2 = MHZ19B_Read_CO2();
    if (g_sensor_data.air_co2 == 0) {
        printf("CO2传感器读取失败\r\n");
    }
    
    // 读取光照强度 (BH1750)
    g_sensor_data.light_intensity = BH1750_Read_Lux();
    if (g_sensor_data.light_intensity == 0) {
        printf("光照传感器读取失败\r\n");
    }
    
    // 更新时间戳
    g_sensor_data.timestamp = millis();
    
    printf("传感器数据: 温度=%.1f°C, 湿度=%.1f%%, CO2=%.0fppm, 光照=%.0flux\r\n",
           g_sensor_data.soil_temperature, g_sensor_data.soil_humidity,
           g_sensor_data.air_co2, g_sensor_data.light_intensity);
}

// 执行自动控制
void Control_Execute(void) {
    CropTemplate *crop = &g_crop_templates[g_system_status.current_crop];
    
    // 水泵控制 (土壤湿度)
    if (g_sensor_data.soil_humidity < crop->soil_humidity_min) {
        // 土壤湿度过低，开启水泵
        GPIO_SetBits(GPIOC, GPIO_Pin_0);
        g_system_status.pump_status = 1;
        printf("土壤湿度过低，开启水泵灌溉\r\n");
    } else if (g_sensor_data.soil_humidity > crop->soil_humidity_max) {
        // 土壤湿度过高，关闭水泵
        GPIO_ResetBits(GPIOC, GPIO_Pin_0);
        g_system_status.pump_status = 0;
        printf("土壤湿度过高，关闭水泵\r\n");
    }
    
    // 加热灯控制 (土壤温度)
    if (g_sensor_data.soil_temperature < crop->soil_temp_min) {
        // 温度过低，开启加热灯
        GPIO_SetBits(GPIOC, GPIO_Pin_1);
        g_system_status.heater_status = 1;
        printf("温度过低，开启加热灯\r\n");
    } else if (g_sensor_data.soil_temperature > crop->soil_temp_max) {
        // 温度过高，关闭加热灯
        GPIO_ResetBits(GPIOC, GPIO_Pin_1);
        g_system_status.heater_status = 0;
        printf("温度过高，关闭加热灯\r\n");
    }
}

// 数据上传
void Data_Upload(void) {
    if (g_system_status.wifi_connected) {
        char json_buffer[256];
        CropTemplate *crop = &g_crop_templates[g_system_status.current_crop];
        
        // 构建JSON数据
        snprintf(json_buffer, sizeof(json_buffer),
                "{\"node_id\":%d,\"timestamp\":%lu,\"soil_temp\":%.1f,\"soil_humidity\":%.1f,\"co2\":%.0f,\"light\":%.0f,\"pump\":%d,\"heater\":%d,\"crop\":\"%s\"}",
                NODE_ID, g_sensor_data.timestamp, 
                g_sensor_data.soil_temperature, g_sensor_data.soil_humidity,
                g_sensor_data.air_co2, g_sensor_data.light_intensity,
                g_system_status.pump_status, g_system_status.heater_status,
                crop->name);
        
        // 通过ESP8266发送数据
        if (ESP8266_Send_Data(json_buffer) == 0) {
            printf("数据上传成功\r\n");
            GPIO_SetBits(GPIOC, GPIO_Pin_3); // 点亮状态LED
            Delay_ms(100);
            GPIO_ResetBits(GPIOC, GPIO_Pin_3);
        } else {
            printf("数据上传失败\r\n");
        }
    } else {
        printf("WiFi未连接，跳过数据上传\r\n");
    }
}

// OLED显示数据
void OLED_Display_Data(void) {
    char display_buffer[32];
    CropTemplate *crop = &g_crop_templates[g_system_status.current_crop];
    
    // 清空屏幕
    SSD1306_Clear();
    
    // 显示标题
    SSD1306_SetCursor(0, 0);
    SSD1306_WriteString("智能大棚监控系统", Font_7x10);
    
    // 显示节点ID和作物
    SSD1306_SetCursor(0, 12);
    snprintf(display_buffer, sizeof(display_buffer), "节点:%d 作物:%s", NODE_ID, crop->name);
    SSD1306_WriteString(display_buffer, Font_6x8);
    
    // 显示传感器数据
    SSD1306_SetCursor(0, 22);
    snprintf(display_buffer, sizeof(display_buffer), "土温:%.1fC 土湿:%.1f%%", 
            g_sensor_data.soil_temperature, g_sensor_data.soil_humidity);
    SSD1306_WriteString(display_buffer, Font_6x8);
    
    SSD1306_SetCursor(0, 32);
    snprintf(display_buffer, sizeof(display_buffer), "CO2:%.0fppm 光照:%.0flux", 
            g_sensor_data.air_co2, g_sensor_data.light_intensity);
    SSD1306_WriteString(display_buffer, Font_6x8);
    
    // 显示执行器状态
    SSD1306_SetCursor(0, 42);
    snprintf(display_buffer, sizeof(display_buffer), "水泵:%s 加热:%s", 
            g_system_status.pump_status ? "开" : "关",
            g_system_status.heater_status ? "开" : "关");
    SSD1306_WriteString(display_buffer, Font_6x8);
    
    // 显示WiFi状态
    SSD1306_SetCursor(0, 52);
    snprintf(display_buffer, sizeof(display_buffer), "WiFi:%s 模式:%s", 
            g_system_status.wifi_connected ? "已连接" : "未连接",
            g_system_status.auto_mode ? "自动" : "手动");
    SSD1306_WriteString(display_buffer, Font_6x8);
    
    // 更新显示
    SSD1306_UpdateScreen();
}

// 报警检查
void Alarm_Check(void) {
    static uint32_t last_alarm_time = 0;
    uint32_t current_time = millis();
    CropTemplate *crop = &g_crop_templates[g_system_status.current_crop];
    uint8_t need_alarm = 0;
    
    // 检查各项参数是否超出范围
    if (g_sensor_data.soil_temperature < crop->soil_temp_min ||
        g_sensor_data.soil_temperature > crop->soil_temp_max) {
        need_alarm = 1;
    }
    
    if (g_sensor_data.soil_humidity < crop->soil_humidity_min ||
        g_sensor_data.soil_humidity > crop->soil_humidity_max) {
        need_alarm = 1;
    }
    
    if (g_sensor_data.air_co2 < crop->co2_min ||
        g_sensor_data.air_co2 > crop->co2_max) {
        need_alarm = 1;
    }
    
    if (g_sensor_data.light_intensity < crop->light_min ||
        g_sensor_data.light_intensity > crop->light_max) {
        need_alarm = 1;
    }
    
    // 触发报警
    if (need_alarm && (current_time - last_alarm_time > 10000)) { // 10秒间隔
        printf("参数异常报警！\r\n");
        
        // 本地蜂鸣器报警
        GPIO_SetBits(GPIOC, GPIO_Pin_2);
        Delay_ms(500);
        GPIO_ResetBits(GPIOC, GPIO_Pin_2);
        
        last_alarm_time = current_time;
    }
}

// 延时函数
void Delay_ms(uint32_t ms) {
    uint32_t i;
    for (i = 0; i < ms; i++) {
        Delay_us(1000);
    }
}

void Delay_us(uint32_t us) {
    uint32_t count = us * 8; // 72MHz时钟
    while (count--) {
        __NOP();
    }
}

// 获取系统运行时间 (毫秒)
uint32_t millis(void) {
    return TIM2->CNT; // 简化的毫秒计数
}

// 定时器2中断服务函数
void TIM2_IRQHandler(void) {
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
        // 毫秒计数器更新
        static uint32_t ms_counter = 0;
        ms_counter++;
    }
}

// printf重定向
int fputc(int ch, FILE *f) {
    USART_SendData(USART1, (uint8_t)ch);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    return ch;
}
